home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Games
/
MAME
/
src
/
cpu
/
m6502
/
6502dasm.c
next >
Wrap
C/C++ Source or Header
|
2000-05-18
|
36KB
|
969 lines
/*****************************************************************************
*
* 6502dasm.c
* 6502/65c02/6510 disassembler
*
* Copyright (c) 1998 Juergen Buchmueller, all rights reserved.
*
* - This source code is released as freeware for non-commercial purposes.
* - You are free to use and redistribute this code in modified or
* unmodified form, provided you list me in the credits.
* - If you modify this source code, you must add a notice to each modified
* source file that it has been changed. If you're a nice person, you
* will clearly mark each change too. :)
* - If you wish to use this for commercial purposes, please contact me at
* pullmoll@t-online.de
* - The author of this copywritten work reserves the right to change the
* terms of its usage and license at any time, including retroactively
* - This entire notice must remain in the source code.
*
*****************************************************************************/
/* 2. February 2000 PeT added support for 65sc02 subtype */
/* 2. February 2000 PeT added support for 65ce02 variant */
/* 3. February 2000 PeT bbr bbs displayment */
/* 4. February 2000 PeT ply inw dew */
/* 4. February 2000 PeT fixed relative word operand */
/* 9. May 2000 PeT added m4510 */
#include <stdio.h>
#ifdef MAME_DEBUG
#include "driver.h"
#include "mamedbg.h"
#include "m6502.h"
#if (HAS_M65CE02)
#include "m65ce02.h"
#endif
#if (HAS_M6509)
#include "m6509.h"
#endif
#if (HAS_M4510)
#include "m4510.h"
#endif
#define OPCODE(A) cpu_readop(A)
#define ARGBYTE(A) cpu_readop_arg(A)
#define ARGWORD(A) cpu_readop_arg(A)+(cpu_readop_arg((A+1) & 0xffff) << 8)
#define RDMEM(A) cpu_readmem16(A)
enum addr_mode {
non, /* no additional arguments */
imp, /* implicit */
acc, /* accumulator */
imm, /* immediate */
iw2, /* immediate word (65ce02) */
adr, /* absolute address (jmp,jsr) */
aba, /* absolute */
zpg, /* zero page */
zpx, /* zero page + X */
zpy, /* zero page + Y */
zpi, /* zero page indirect (65c02) */
zpb, /* zero page and branch (65c02 bbr,bbs) */
abx, /* absolute + X */
aby, /* absolute + Y */
rel, /* relative */
rw2, /* relative word (65cs02, 65ce02) */
idx, /* zero page pre indexed */
idy, /* zero page post indexed */
idz, /* zero page post indexed (65ce02) */
isy, /* zero page pre indexed sp and post indexed y (65ce02) */
ind, /* indirect (jmp) */
iax /* indirect + X (65c02 jmp) */
};
enum opcodes {
adc, and, asl, bcc, bcs, beq, bit, bmi,
bne, bpl, brk, bvc, bvs, clc, cld, cli,
clv, cmp, cpx, cpy, dec, dex, dey, eor,
inc, inx, iny, jmp, jsr, lda, ldx, ldy,
lsr, nop, ora, pha, php, pla, plp, rol,
ror, rti, rts, sbc, sec, sed, sei, sta,
stx, sty, tax, tay, tsx, txa, txs, tya,
ill,
/* 65c02 (only) mnemonics */
bbr, bbs, bra, rmb, smb, stz, trb, tsb,
/* 65sc02 (only) mnemonics */
bsr,
/* 6510 + 65c02 mnemonics */
anc, asr, ast, arr, asx, axa, dcp, dea,
dop, ina, isc, lax, phx, phy, plx, ply,
rla, rra, sax, slo, sre, sah, say, ssh,
sxh, syh, top, oal, kil,
/* 65ce02 mnemonics */
cle, see, map,
tab, tba, taz, tza, tys, tsy,
ldz, stz2/* real register store */,
dez, inz, cpz, phz, plz,
neg, asr2/* arithmetic shift right */,
asw, row, dew, inw, phw
};
static const char *token[]=
{
"adc", "and", "asl", "bcc", "bcs", "beq", "bit", "bmi",
"bne", "bpl", "brk", "bvc", "bvs", "clc", "cld", "cli",
"clv", "cmp", "cpx", "cpy", "dec", "dex", "dey", "eor",
"inc", "inx", "iny", "jmp", "jsr", "lda", "ldx", "ldy",
"lsr", "nop", "ora", "pha", "php", "pla", "plp", "rol",
"ror", "rti", "rts", "sbc", "sec", "sed", "sei", "sta",
"stx", "sty", "tax", "tay", "tsx", "txa", "txs", "tya",
"ill",
/* 65c02 mnemonics */
"bbr", "bbs", "bra", "rmb", "smb", "stz", "trb", "tsb",
/* 65sc02 (only) mnemonics */
"bsr",
/* 6510 mnemonics */
"anc", "asr", "ast", "arr", "asx", "axa", "dcp", "dea",
"dop", "ina", "isc", "lax", "phx", "phy", "plx", "ply",
"rla", "rra", "sax", "slo", "sre", "sah", "say", "ssh",
"sxh", "syh", "top", "oal", "kil",
/* 65ce02 mnemonics */
"cle", "see", "map",
"tab", "tba", "taz", "tza", "tys", "tsy",
"ldz", "stz",
"dez", "inz", "cpz", "phz", "plz",
"neg", "asr",
"asw", "row", "dew", "inw", "phw"
};
/* Some really short names for the EA access modes */
#define VAL EA_VALUE
#define JMP EA_ABS_PC
#define BRA EA_REL_PC
#define MRD EA_MEM_RD
#define MWR EA_MEM_WR
#define MRW EA_MEM_RDWR
#define ZRD EA_ZPG_RD
#define ZWR EA_ZPG_WR
#define ZRW EA_ZPG_RDWR
/* words */
#define MRD2 EA_MEM_RD
#define MRW2 EA_MEM_RDWR
#define ZRD2 EA_ZPG_RD
#define ZRW2 EA_ZPG_RDWR
static const UINT8 op6502[256][3] = {
{brk,imm,VAL},{ora,idx,MRD},{ill,non,0 },{ill,non,0 },/* 00 */
{ill,non,0 },{ora,zpg,ZRD},{asl,zpg,ZRW},{ill,non,0 },
{php,imp,0 },{ora,imm,VAL},{asl,acc,0 },{ill,non,0 },
{ill,non,0 },{ora,aba,MRD},{asl,aba,MRW},{ill,non,0 },
{bpl,rel,BRA},{ora,idy,MRD},{ill,non,0 },{ill,non,0 },/* 10 */
{ill,non,0 },{ora,zpx,ZRD},{asl,zpx,ZRW},{ill,non,0 },
{clc,imp,0 },{ora,aby,MRD},{ill,non,0 },{ill,non,0 },
{ill,non,0 },{ora,abx,MRD},{asl,abx,MRW},{ill,non,0 },
{jsr,adr,JMP},{and,idx,MRD},{ill,non,0 },{ill,non,0 },/* 20 */
{bit,zpg,ZRD},{and,zpg,ZRD},{rol,zpg,ZRW},{ill,non,0 },
{plp,imp,0 },{and,imm,VAL},{rol,acc,0 },{ill,non,0 },
{bit,aba,MRD},{and,aba,MRD},{rol,aba,MRW},{ill,non,0 },
{bmi,rel,BRA},{and,idy,MRD},{ill,non,0 },{ill,non,0 },/* 30 */
{ill,non,0 },{and,zpx,ZRD},{rol,zpx,ZRW},{ill,non,0 },
{sec,imp,0 },{and,aby,MRD},{ill,non,0 },{ill,non,0 },
{ill,non,0 },{and,abx,MRD},{rol,abx,MRW},{ill,non,0 },
{rti,imp,0 },{eor,idx,MRD},{ill,non,0 },{ill,non,0 },/* 40 */
{ill,non,0 },{eor,zpg,ZRD},{lsr,zpg,ZRW},{ill,non,0 },
{pha,imp,0 },{eor,imm,VAL},{lsr,acc,0 },{ill,non,0 },
{jmp,adr,JMP},{eor,aba,MRD},{lsr,aba,MRW},{ill,non,0 },
{bvc,rel,BRA},{eor,idy,MRD},{ill,non,0 },{ill,non,0 },/* 50 */
{ill,non,0 },{eor,zpx,ZRD},{lsr,zpx,ZRW},{ill,non,0 },
{cli,imp,0 },{eor,aby,MRD},{ill,non,0 },{ill,non,0 },
{ill,non,0 },{eor,abx,MRD},{lsr,abx,MRW},{ill,non,0 },
{rts,imp,0 },{adc,idx,MRD},{ill,non,0 },{ill,non,0 },/* 60 */
{ill,non,0 },{adc,zpg,ZRD},{ror,zpg,ZRW},{ill,non,0 },
{pla,imp,0 },{adc,imm,VAL},{ror,acc,0 },{ill,non,0 },
{jmp,ind,JMP},{adc,aba,MRD},{ror,aba,MRW},{ill,non,0 },
{bvs,rel,BRA},{adc,idy,MRD},{ill,non,0 },{ill,non,0 },/* 70 */
{ill,non,0 },{adc,zpx,ZRD},{ror,zpx,ZRW},{ill,non,0 },
{sei,imp,0 },{adc,aby,MRD},{ill,non,0 },{ill,non,0 },
{ill,non,0 },{adc,abx,MRD},{ror,abx,MRW},{ill,non,0 },
{ill,non,0 },{sta,idx,MWR},{ill,non,0 },{ill,non,0 },/* 80 */
{sty,zpg,ZWR},{sta,zpg,ZWR},{stx,zpg,ZWR},{ill,non,0 },
{dey,imp,0 },{ill,non,0 },{txa,imp,0 },{ill,non,0 },
{sty,aba,MWR},{sta,aba,MWR},{stx,aba,MWR},{ill,non,0 },
{bcc,rel,BRA},{sta,idy,MWR},{ill,non,0 },{ill,non,0 },/* 90 */
{sty,zpx,ZWR},{sta,zpx,ZWR},{stx,zpy,ZWR},{ill,non,0 },
{tya,imp,0 },{sta,aby,MWR},{txs,imp,0 },{ill,non,0 },
{ill,non,0 },{sta,abx,MWR},{ill,non,0 },{ill,non,0 },
{ldy,imm,VAL},{lda,idx,MRD},{ldx,imm,VAL},{ill,non,0 },/* a0 */
{ldy,zpg,ZRD},{lda,zpg,ZRD},{ldx,zpg,ZRD},{ill,non,0 },
{tay,imp,0 },{lda,imm,VAL},{tax,imp,0 },{ill,non,0 },
{ldy,aba,MRD},{lda,aba,MRD},{ldx,aba,MRD},{ill,non,0 },
{bcs,rel,BRA},{lda,idy,MRD},{ill,non,0 },{ill,non,0 },/* b0 */
{ldy,zpx,ZRD},{lda,zpx,ZRD},{ldx,zpy,ZRD},{ill,non,0 },
{clv,imp,0 },{lda,aby,MRD},{tsx,imp,0 },{ill,non,0 },
{ldy,abx,MRD},{lda,abx,MRD},{ldx,aby,MRD},{ill,non,0 },
{cpy,imm,VAL},{cmp,idx,MRD},{ill,non,0 },{ill,non,0 },/* c0 */
{cpy,zpg,ZRD},{cmp,zpg,ZRD},{dec,zpg,ZRW},{ill,non,0 },
{iny,imp,0 },{cmp,imm,VAL},{dex,imp,0 },{ill,non,0 },
{cpy,aba,MRD},{cmp,aba,MRD},{dec,aba,MRW},{ill,non,0 },
{bne,rel,BRA},{cmp,idy,MRD},{ill,non,0 },{ill,non,0 },/* d0 */
{ill,non,0 },{cmp,zpx,ZRD},{dec,zpx,ZRW},{ill,non,0 },
{cld,imp,0 },{cmp,aby,MRD},{ill,non,0 },{ill,non,0 },
{ill,non,0 },{cmp,abx,MRD},{dec,abx,MRW},{ill,non,0 },
{cpx,imm,VAL},{sbc,idx,MRD},{ill,non,0 },{ill,non,0 },/* e0 */
{cpx,zpg,ZRD},{sbc,zpg,ZRD},{inc,zpg,ZRW},{ill,non,0 },
{inx,imp,0 },{sbc,imm,VAL},{nop,imp,0 },{ill,non,0 },
{cpx,aba,MRD},{sbc,aba,MRD},{inc,aba,MRW},{ill,non,0 },
{beq,rel,BRA},{sbc,idy,MRD},{ill,non,0 },{ill,non,0 },/* f0 */
{ill,non,0 },{sbc,zpx,ZRD},{inc,zpx,ZRW},{ill,non,0 },
{sed,imp,0 },{sbc,aby,MRD},{ill,non,0 },{ill,non,0 },
{ill,non,0 },{sbc,abx,MRD},{inc,abx,MRW},{ill,non,0 }
};
static const UINT8 op65c02[256][3] = {
{brk,imm,VAL},{ora,idx,MRD},{ill,non,0 },{ill,non,0 },/* 00 */
{tsb,zpg,0 },{ora,zpg,ZRD},{asl,zpg,ZRW},{rmb,zpg,ZRW},
{php,imp,0 },{ora,imm,VAL},{asl,acc,MRW},{ill,non,0 },
{tsb,aba,MRD},{ora,aba,MRD},{asl,aba,MRW},{bbr,zpb,ZRD},
{bpl,rel,BRA},{ora,idy,MRD},{ora,zpi,MRD},{ill,non,0 },/* 10 */
{trb,zpg,ZRD},{ora,zpx,ZRD},{asl,zpx,ZRW},{rmb,zpg,ZRW},
{clc,imp,0 },{ora,aby,MRD},{ina,imp,0 },{ill,non,0 },
{tsb,aba,MRD},{ora,abx,MRD},{asl,abx,MRW},{bbr,zpb,ZRD},
{jsr,adr,0 },{and,idx,MRD},{ill,non,0 },{ill,non,0 },/* 20 */
{bit,zpg,ZRD},{and,zpg,ZRD},{rol,zpg,ZRW},{rmb,zpg,ZRW},
{plp,imp,0 },{and,imm,VAL},{rol,acc,0 },{ill,non,0 },
{bit,aba,MRD},{and,aba,MRD},{rol,aba,MRW},{bbr,zpb,ZRD},
{bmi,rel,BRA},{and,idy,MRD},{and,zpi,MRD},{ill,non,0 },/* 30 */
{bit,zpx,ZRD},{and,zpx,ZRD},{rol,zpx,ZRW},{rmb,zpg,ZRW},
{sec,imp,0 },{and,aby,MRD},{dea,imp,0 },{ill,non,0 },
{bit,abx,MRD},{and,abx,MRD},{rol,abx,MRW},{bbr,zpb,ZRD},
{rti,imp,0 },{eor,idx,MRD},{ill,non,0 },{ill,non,0 },/* 40 */
{ill,non,0 },{eor,zpg,ZRD},{lsr,zpg,ZRW},{rmb,zpg,ZRW},
{pha,imp,0 },{eor,imm,VAL},{lsr,acc,0 },{ill,non,0 },
{jmp,adr,JMP},{eor,aba,MRD},{lsr,aba,MRW},{bbr,zpb,ZRD},
{bvc,rel,BRA},{eor,idy,MRD},{eor,zpi,MRD},{ill,non,0 },/* 50 */
{ill,non,0 },{eor,zpx,ZRD},{lsr,zpx,ZRW},{rmb,zpg,ZRW},
{cli,imp,0 },{eor,aby,MRD},{phy,imp,0 },{ill,non,0 },
{ill,non,0 },{eor,abx,MRD},{lsr,abx,MRW},{bbr,zpb,ZRD},
{rts,imp,0 },{adc,idx,MRD},{ill,non,0 },{ill,non,0 },/* 60 */
{stz,zpg,ZWR},{adc,zpg,ZRD},{ror,zpg,ZRW},{rmb,zpg,ZRW},
{pla,imp,0 },{adc,imm,VAL},{ror,acc,0 },{ill,non,0 },
{jmp,ind,JMP},{adc,aba,MRD},{ror,aba,MRW},{bbr,zpb,ZRD},
{bvs,rel,BRA},{adc,idy,MRD},{adc,zpi,MRD},{ill,non,0 },/* 70 */
{stz,zpx,ZWR},{adc,zpx,ZRD},{ror,zpx,ZRW},{rmb,zpg,ZRW},
{sei,imp,0 },{adc,aby,MRD},{ply,imp,0 },{ill,non,0 },
{jmp,iax,JMP},{adc,abx,MRD},{ror,abx,MRW},{bbr,zpb,ZRD},
{bra,rel,BRA},{sta,idx,MWR},{ill,non,0 },{ill,non,0 },/* 80 */
{sty,zpg,ZWR},{sta,zpg,ZWR},{stx,zpg,ZWR},{smb,zpg,ZRW},
{dey,imp,0 },{bit,imm,VAL},{txa,imp,0 },{ill,non,0 },
{sty,aba,MWR},{sta,aba,MWR},{stx,aba,MWR},{bbs,zpb,ZRD},
{bcc,rel,BRA},{sta,idy,MWR},{sta,zpi,MWR},{ill,non,0 },/* 90 */
{sty,zpx,ZWR},{sta,zpx,ZWR},{stx,zpy,ZWR},{smb,zpg,ZRW},
{tya,imp,0 },{sta,aby,MWR},{txs,imp,0 },{ill,non,0 },
{stz,aba,MWR},{sta,abx,MWR},{stz,abx,MWR},{bbs,zpb,ZRD},
{ldy,imm,VAL},{lda,idx,MRD},{ldx,imm,VAL},{ill,non,0 },/* a0 */
{ldy,zpg,ZRD},{lda,zpg,ZRD},{ldx,zpg,ZRD},{smb,zpg,ZRW},
{tay,imp,0 },{lda,imm,VAL},{tax,imp,0 },{ill,non,0 },
{ldy,aba,MRD},{lda,aba,MRD},{ldx,aba,MRD},{bbs,zpb,ZRD},
{bcs,rel,BRA},{lda,idy,MRD},{lda,zpi,MRD},{ill,non,0 },/* b0 */
{ldy,zpx,ZRD},{lda,zpx,ZRD},{ldx,zpy,ZRD},{smb,zpg,ZRW},
{clv,imp,0 },{lda,aby,MRD},{tsx,imp,0 },{ill,non,0 },
{ldy,abx,MRD},{lda,abx,MRD},{ldx,aby,MRD},{bbs,zpb,ZRD},
{cpy,imm,VAL},{cmp,idx,MRD},{ill,non,0 },{ill,non,0 },/* c0 */
{cpy,zpg,ZRD},{cmp,zpg,ZRD},{dec,zpg,ZRW},{smb,zpg,ZRW},
{iny,imp,0 },{cmp,imm,VAL},{dex,imp,0 },{ill,non,0 },
{cpy,aba,MRD},{cmp,aba,MRD},{dec,aba,MRW},{bbs,zpb,ZRD},
{bne,rel,BRA},{cmp,idy,MRD},{cmp,zpi,MRD},{ill,non,0 },/* d0 */
{ill,non,0 },{cmp,zpx,ZRD},{dec,zpx,ZRW},{smb,zpg,ZRW},
{cld,imp,0 },{cmp,aby,MRD},{phx,imp,0 },{ill,non,0 },
{ill,non,0 },{cmp,abx,MRD},{dec,abx,MRW},{bbs,zpb,ZRD},
{cpx,imm,VAL},{sbc,idx,MRD},{ill,non,0 },{ill,non,0 },/* e0 */
{cpx,zpg,ZRD},{sbc,zpg,ZRD},{inc,zpg,ZRW},{smb,zpg,ZRW},
{inx,imp,0 },{sbc,imm,VAL},{nop,imp,0 },{ill,non,0 },
{cpx,aba,MRD},{sbc,aba,MRD},{inc,aba,MRW},{bbs,zpb,ZRD},
{beq,rel,BRA},{sbc,idy,MRD},{sbc,zpi,MRD},{ill,non,0 },/* f0 */
{ill,non,0 },{sbc,zpx,ZRD},{inc,zpx,ZRW},{smb,zpg,ZRW},
{sed,imp,0 },{sbc,aby,MRD},{plx,imp,0 },{ill,non,0 },
{ill,non,0 },{sbc,abx,MRD},{inc,abx,MRW},{bbs,zpb,ZRD}
};
/* only bsr additional to 65c02 yet */
static const UINT8 op65sc02[256][3] = {
{brk,imm,VAL},{ora,idx,MRD},{ill,non,0 },{ill,non,0 },/* 00 */
{tsb,zpg,0 },{ora,zpg,ZRD},{asl,zpg,ZRW},{rmb,zpg,ZRW},
{php,imp,0 },{ora,imm,VAL},{asl,acc,MRW},{ill,non,0 },
{tsb,aba,MRD},{ora,aba,MRD},{asl,aba,MRW},{bbr,zpb,ZRD},
{bpl,rel,BRA},{ora,idy,MRD},{ora,zpi,MRD},{ill,non,0 },/* 10 */
{trb,zpg,ZRD},{ora,zpx,ZRD},{asl,zpx,ZRW},{rmb,zpg,ZRW},
{clc,imp,0 },{ora,aby,MRD},{ina,imp,0 },{ill,non,0 },
{tsb,aba,MRD},{ora,abx,MRD},{asl,abx,MRW},{bbr,zpb,ZRD},
{jsr,adr,0 },{and,idx,MRD},{ill,non,0 },{ill,non,0 },/* 20 */
{bit,zpg,ZRD},{and,zpg,ZRD},{rol,zpg,ZRW},{rmb,zpg,ZRW},
{plp,imp,0 },{and,imm,VAL},{rol,acc,0 },{ill,non,0 },
{bit,aba,MRD},{and,aba,MRD},{rol,aba,MRW},{bbr,zpb,ZRD},
{bmi,rel,BRA},{and,idy,MRD},{and,zpi,MRD},{ill,non,0 },/* 30 */
{bit,zpx,ZRD},{and,zpx,ZRD},{rol,zpx,ZRW},{rmb,zpg,ZRW},
{sec,imp,0 },{and,aby,MRD},{dea,imp,0 },{ill,non,0 },
{bit,abx,MRD},{and,abx,MRD},{rol,abx,MRW},{bbr,zpb,ZRD},
{rti,imp,0 },{eor,idx,MRD},{ill,non,0 },{ill,non,0 },/* 40 */
{ill,non,0 },{eor,zpg,ZRD},{lsr,zpg,ZRW},{rmb,zpg,ZRW},
{pha,imp,0 },{eor,imm,VAL},{lsr,acc,0 },{ill,non,0 },
{jmp,adr,JMP},{eor,aba,MRD},{lsr,aba,MRW},{bbr,zpb,ZRD},
{bvc,rel,BRA},{eor,idy,MRD},{eor,zpi,MRD},{ill,non,0 },/* 50 */
{ill,non,0 },{eor,zpx,ZRD},{lsr,zpx,ZRW},{rmb,zpg,ZRW},
{cli,imp,0 },{eor,aby,MRD},{phy,imp,0 },{ill,non,0 },
{ill,non,0 },{eor,abx,MRD},{lsr,abx,MRW},{bbr,zpb,ZRD},
{rts,imp,0 },{adc,idx,MRD},{ill,non,0 },{bsr,rw2,BRA},/* 60 */
{stz,zpg,ZWR},{adc,zpg,ZRD},{ror,zpg,ZRW},{rmb,zpg,ZRW},
{pla,imp,0 },{adc,imm,VAL},{ror,acc,0 },{ill,non,0 },
{jmp,ind,JMP},{adc,aba,MRD},{ror,aba,MRW},{bbr,zpb,ZRD},
{bvs,rel,BRA},{adc,idy,MRD},{adc,zpi,MRD},{ill,non,0 },/* 70 */
{stz,zpx,ZWR},{adc,zpx,ZRD},{ror,zpx,ZRW},{rmb,zpg,ZRW},
{sei,imp,0 },{adc,aby,MRD},{ply,imp,0 },{ill,non,0 },
{jmp,iax,JMP},{adc,abx,MRD},{ror,abx,MRW},{bbr,zpb,ZRD},
{bra,rel,BRA},{sta,idx,MWR},{ill,non,0 },{ill,non,0 },/* 80 */
{sty,zpg,ZWR},{sta,zpg,ZWR},{stx,zpg,ZWR},{smb,zpg,ZRW},
{dey,imp,0 },{bit,imm,VAL},{txa,imp,0 },{ill,non,0 },
{sty,aba,MWR},{sta,aba,MWR},{stx,aba,MWR},{bbs,zpb,ZRD},
{bcc,rel,BRA},{sta,idy,MWR},{sta,zpi,MWR},{ill,non,0 },/* 90 */
{sty,zpx,ZWR},{sta,zpx,ZWR},{stx,zpy,ZWR},{smb,zpg,ZRW},
{tya,imp,0 },{sta,aby,MWR},{txs,imp,0 },{ill,non,0 },
{stz,aba,MWR},{sta,abx,MWR},{stz,abx,MWR},{bbs,zpb,ZRD},
{ldy,imm,VAL},{lda,idx,MRD},{ldx,imm,VAL},{ill,non,0 },/* a0 */
{ldy,zpg,ZRD},{lda,zpg,ZRD},{ldx,zpg,ZRD},{smb,zpg,ZRW},
{tay,imp,0 },{lda,imm,VAL},{tax,imp,0 },{ill,non,0 },
{ldy,aba,MRD},{lda,aba,MRD},{ldx,aba,MRD},{bbs,zpb,ZRD},
{bcs,rel,BRA},{lda,idy,MRD},{lda,zpi,MRD},{ill,non,0 },/* b0 */
{ldy,zpx,ZRD},{lda,zpx,ZRD},{ldx,zpy,ZRD},{smb,zpg,ZRW},
{clv,imp,0 },{lda,aby,MRD},{tsx,imp,0 },{ill,non,0 },
{ldy,abx,MRD},{lda,abx,MRD},{ldx,aby,MRD},{bbs,zpb,ZRD},
{cpy,imm,VAL},{cmp,idx,MRD},{ill,non,0 },{ill,non,0 },/* c0 */
{cpy,zpg,ZRD},{cmp,zpg,ZRD},{dec,zpg,ZRW},{smb,zpg,ZRW},
{iny,imp,0 },{cmp,imm,VAL},{dex,imp,0 },{ill,non,0 },
{cpy,aba,MRD},{cmp,aba,MRD},{dec,aba,MRW},{bbs,zpb,ZRD},
{bne,rel,BRA},{cmp,idy,MRD},{cmp,zpi,MRD},{ill,non,0 },/* d0 */
{ill,non,0 },{cmp,zpx,ZRD},{dec,zpx,ZRW},{smb,zpg,ZRW},
{cld,imp,0 },{cmp,aby,MRD},{phx,imp,0 },{ill,non,0 },
{ill,non,0 },{cmp,abx,MRD},{dec,abx,MRW},{bbs,zpb,ZRD},
{cpx,imm,VAL},{sbc,idx,MRD},{ill,non,0 },{ill,non,0 },/* e0 */
{cpx,zpg,ZRD},{sbc,zpg,ZRD},{inc,zpg,ZRW},{smb,zpg,ZRW},
{inx,imp,0 },{sbc,imm,VAL},{nop,imp,0 },{ill,non,0 },
{cpx,aba,MRD},{sbc,aba,MRD},{inc,aba,MRW},{bbs,zpb,ZRD},
{beq,rel,BRA},{sbc,idy,MRD},{sbc,zpi,MRD},{ill,non,0 },/* f0 */
{ill,non,0 },{sbc,zpx,ZRD},{inc,zpx,ZRW},{smb,zpg,ZRW},
{sed,imp,0 },{sbc,aby,MRD},{plx,imp,0 },{ill,non,0 },
{ill,non,0 },{sbc,abx,MRD},{inc,abx,MRW},{bbs,zpb,ZRD}
};
static const UINT8 op6510[256][3] = {
{brk,imm,VAL},{ora,idx,MRD},{kil,non,0 },{slo,idx,MRW},/* 00 */
{dop,imm,VAL},{ora,zpg,ZRD},{asl,zpg,ZRW},{slo,zpg,ZRW},
{php,imp,0 },{ora,imm,VAL},{asl,acc,0 },{anc,imm,VAL},
{top,iw2,VAL},{ora,aba,MRD},{asl,aba,MRW},{slo,aba,MRW},
{bpl,rel,BRA},{ora,idy,MRD},{nop,imp,0 },{slo,idy,MRW},/* 10 */
{dop,imm,VAL},{ora,zpx,ZRD},{asl,zpx,ZRW},{slo,zpx,ZRW},
{clc,imp,0 },{ora,aby,MRD},{kil,non,0 },{slo,aby,MRW},
{top,iw2,VAL},{ora,abx,MRD},{asl,abx,MRW},{slo,abx,MRW},
{jsr,adr,JMP},{and,idx,MRD},{kil,non,0 },{rla,idx,MRW},/* 20 */
{bit,zpg,ZRD},{and,zpg,ZRD},{rol,zpg,ZRW},{rla,zpg,ZRW},
{plp,imp,0 },{and,imm,VAL},{rol,acc,0 },{anc,imm,VAL},
{bit,aba,MRD},{and,aba,MRD},{rol,aba,MRW},{rla,aba,MRW},
{bmi,rel,BRA},{and,idy,MRD},{kil,non,0 },{rla,idy,MRW},/* 30 */
{dop,imm,VAL},{and,zpx,ZRD},{rol,zpx,ZRW},{rla,zpx,ZRW},
{sec,imp,0 },{and,aby,MRD},{nop,imp,0 },{rla,aby,MRW},
{top,iw2,VAL},{and,abx,MRD},{rol,abx,MRW},{rla,abx,MRW},
{rti,imp,0 },{eor,idx,MRD},{kil,non,0 },{sre,idx,MRW},/* 40 */
{dop,imm,VAL},{eor,zpg,ZRD},{lsr,zpg,ZRW},{sre,zpg,ZRW},
{pha,imp,0 },{eor,imm,VAL},{lsr,acc,0 },{asr,imm,VAL},
{jmp,adr,JMP},{eor,aba,MRD},{lsr,aba,MRW},{sre,aba,MRW},
{bvc,rel,BRA},{eor,idy,MRD},{kil,non,0 },{sre,idy,MRW},/* 50 */
{dop,imm,VAL},{eor,zpx,ZRD},{lsr,zpx,ZRW},{sre,zpx,ZRW},
{cli,imp,0 },{eor,aby,MRD},{nop,imp,0 },{sre,aby,MRW},
{top,iw2,VAL},{eor,abx,MRD},{lsr,abx,MRW},{sre,abx,MRW},
{rts,imp,0 },{adc,idx,MRD},{kil,non,0 },{rra,idx,MRW},/* 60 */
{dop,imm,VAL},{adc,zpg,ZRD},{ror,zpg,ZRW},{rra,zpg,ZRW},
{pla,imp,0 },{adc,imm,VAL},{ror,acc,0 },{arr,imm,VAL},
{jmp,ind,JMP},{adc,aba,MRD},{ror,aba,MRW},{rra,aba,MRW},
{bvs,rel,BRA},{adc,idy,MRD},{kil,non,0 },{rra,idy,MRW},/* 70 */
{dop,imm,VAL},{adc,zpx,ZRD},{ror,zpx,ZRW},{rra,zpx,ZRW},
{sei,imp,0 },{adc,aby,MRD},{nop,imp,0 },{rra,aby,MRW},
{top,iw2,VAL},{adc,abx,MRD},{ror,abx,MRW},{rra,abx,MRW},
{dop,imm,VAL},{sta,idx,MWR},{dop,imm,VAL},{sax,idx,MWR},/* 80 */
{sty,zpg,ZWR},{sta,zpg,ZWR},{stx,zpg,ZWR},{sax,zpg,ZWR},
{dey,imp,0 },{dop,imm,VAL},{txa,imp,0 },{axa,imm,VAL},
{sty,aba,MWR},{sta,aba,MWR},{stx,aba,MWR},{sax,aba,MWR},
{bcc,rel,BRA},{sta,idy,MWR},{kil,non,0 },{say,idy,MWR},/* 90 */
{sty,zpx,ZWR},{sta,zpx,ZWR},{stx,zpy,ZWR},{sax,zpx,ZWR},
{tya,imp,0 },{sta,aby,MWR},{txs,imp,0 },{ssh,aby,MWR},
{syh,abx,0 },{sta,abx,MWR},{sxh,aby,MWR},{sah,aby,MWR},
{ldy,imm,VAL},{lda,idx,MRD},{ldx,imm,VAL},{lax,idx,MRD},/* a0 */
{ldy,zpg,ZRD},{lda,zpg,ZRD},{ldx,zpg,ZRD},{lax,zpg,ZRD},
{tay,imp,0 },{lda,imm,VAL},{tax,imp,0 },{oal,imm,VAL},
{ldy,aba,MRD},{lda,aba,MRD},{ldx,aba,MRD},{lax,aba,MRD},
{bcs,rel,BRA},{lda,idy,MRD},{kil,non,0 },{lax,idy,MRD},/* b0 */
{ldy,zpx,ZRD},{lda,zpx,ZRD},{ldx,zpy,ZRD},{lax,zpx,ZRD},
{clv,imp,0 },{lda,aby,MRD},{tsx,imp,0 },{ast,aby,MRD},
{ldy,abx,MRD},{lda,abx,MRD},{ldx,aby,MRD},{lax,abx,MRD},
{cpy,imm,VAL},{cmp,idx,MRD},{dop,imm,VAL},{dcp,idx,MRW},/* c0 */
{cpy,zpg,ZRD},{cmp,zpg,ZRD},{dec,zpg,ZRW},{dcp,zpg,ZRW},
{iny,imp,0 },{cmp,imm,VAL},{dex,imp,0 },{asx,imm,VAL},
{cpy,aba,MRD},{cmp,aba,MRD},{dec,aba,MRW},{dcp,aba,MRW},
{bne,rel,BRA},{cmp,idy,MRD},{kil,non,0 },{dcp,idy,MRW},/* d0 */
{dop,imm,VAL},{cmp,zpx,ZRD},{dec,zpx,ZRW},{dcp,zpx,ZRW},
{cld,imp,0 },{cmp,aby,MRD},{nop,imp,0 },{dcp,aby,MRW},
{top,iw2,VAL},{cmp,abx,MRD},{dec,abx,MRW},{dcp,abx,MRW},
{cpx,imm,VAL},{sbc,idx,MRD},{dop,imm,VAL},{isc,idx,MRW},/* e0 */
{cpx,zpg,ZRD},{sbc,zpg,ZRD},{inc,zpg,ZRW},{isc,zpg,ZRW},
{inx,imp,0 },{sbc,imm,VAL},{nop,imp,0 },{sbc,imm,VAL},
{cpx,aba,MRD},{sbc,aba,MRD},{inc,aba,MRW},{isc,aba,MRW},
{beq,rel,BRA},{sbc,idy,MRD},{kil,non,0 },{isc,idy,MRW},/* f0 */
{dop,imm,VAL},{sbc,zpx,ZRD},{inc,zpx,ZRW},{isc,zpx,ZRW},
{sed,imp,0 },{sbc,aby,MRD},{nop,imp,0 },{isc,aby,MRW},
{top,iw2,VAL},{sbc,abx,MRD},{inc,abx,MRW},{isc,abx,MRW}
};
#if (HAS_M65CE02)
static const UINT8 op65ce02[256][3] = {
{brk,imm,VAL},{ora,idx,MRD},{cle,imp,0 },{see,imp,0 },/* 00 */
{tsb,zpg,0 },{ora,zpg,ZRD},{asl,zpg,ZRW},{rmb,zpg,ZRW},
{php,imp,0 },{ora,imm,VAL},{asl,acc,MRW},{tsy,imp,0 },
{tsb,aba,MRD},{ora,aba,MRD},{asl,aba,MRW},{bbr,zpb,ZRD},
{bpl,rel,BRA},{ora,idy,MRD},{ora,idz,MRD},{bpl,rw2,BRA},/* 10 */
{trb,zpg,ZRD},{ora,zpx,ZRD},{asl,zpx,ZRW},{rmb,zpg,ZRW},
{clc,imp,0 },{ora,aby,MRD},{ina,imp,0 },{inz,imp,0 },
{tsb,aba,MRD},{ora,abx,MRD},{asl,abx,MRW},{bbr,zpb,ZRD},
{jsr,adr,0 },{and,idx,MRD},{jsr,ind,0 },{jsr,iax,0 },/* 20 */
{bit,zpg,ZRD},{and,zpg,ZRD},{rol,zpg,ZRW},{rmb,zpg,ZRW},
{plp,imp,0 },{and,imm,VAL},{rol,acc,0 },{tys,imp,0 },
{bit,aba,MRD},{and,aba,MRD},{rol,aba,MRW},{bbr,zpb,ZRD},
{bmi,rel,BRA},{and,idz,MRD},{and,zpi,MRD},{bmi,rw2,BRA},/* 30 */
{bit,zpx,ZRD},{and,zpx,ZRD},{rol,zpx,ZRW},{rmb,zpg,ZRW},
{sec,imp,0 },{and,aby,MRD},{dea,imp,0 },{dez,imp,0 },
{bit,abx,MRD},{and,abx,MRD},{rol,abx,MRW},{bbr,zpb,ZRD},
{rti,imp,0 },{eor,idx,MRD},{neg,imp,0 },{asr2,imp,0 },/* 40 */
{asr2,zpg,ZRW},{eor,zpg,ZRD},{lsr,zpg,ZRW},{rmb,zpg,ZRW},
{pha,imp,0 },{eor,imm,VAL},{lsr,acc,0 },{taz,imp,0 },
{jmp,adr,JMP},{eor,aba,MRD},{lsr,aba,MRW},{bbr,zpb,ZRD},
{bvc,rel,BRA},{eor,idy,MRD},{eor,idz,MRD},{bvc,rw2,BRA},/* 50 */
{asr2,zpx,ZRW},{eor,zpx,ZRD},{lsr,zpx,ZRW},{rmb,zpg,ZRW},
{cli,imp,0 },{eor,aby,MRD},{phy,imp,0 },{tab,imp,0 },
{map,imp,0 },{eor,abx,MRD},{lsr,abx,MRW},{bbr,zpb,ZRD},
{rts,imp,0 },{adc,idx,MRD},{rts,imm,VAL},{bsr,rw2,BRA},/* 60 */
{stz2,zpg,ZWR},{adc,zpg,ZRD},{ror,zpg,ZRW},{rmb,zpg,ZRW},
{pla,imp,0 },{adc,imm,VAL},{ror,acc,0 },{tza,imp,0 },
{jmp,ind,JMP},{adc,aba,MRD},{ror,aba,MRW},{bbr,zpb,ZRD},
{bvs,rel,BRA},{adc,idy,MRD},{adc,zpi,MRD},{bvs,rw2,BRA},/* 70 */
{stz2,zpx,ZWR},{adc,zpx,ZRD},{ror,zpx,ZRW},{rmb,zpg,ZRW},
{sei,imp,0 },{adc,aby,MRD},{ply,imp,0 },{tba,imp,0 },
{jmp,iax,JMP},{adc,abx,MRD},{ror,abx,MRW},{bbr,zpb,ZRD},
{bra,rel,BRA},{sta,idx,MWR},{sta,isy,MWR},{bra,rw2,BRA},/* 80 */
{sty,zpg,ZWR},{sta,zpg,ZWR},{stx,zpg,ZWR},{smb,zpg,ZRW},
{dey,imp,0 },{bit,imm,VAL},{txa,imp,0 },{sty,abx,MWR},
{sty,aba,MWR},{sta,aba,MWR},{stx,aba,MWR},{bbs,zpb,ZRD},
{bcc,rel,BRA},{sta,idy,MWR},{sta,inz,MWR},{bcc,rw2,BRA},/* 90 */
{sty,zpx,ZWR},{sta,zpx,ZWR},{stx,zpy,ZWR},{smb,zpg,ZRW},
{tya,imp,0 },{sta,aby,MWR},{txs,imp,0 },{stx,aby,MWR},
{stz2,aba,MWR},{sta,abx,MWR},{stz2,abx,MWR},{bbs,zpb,ZRD},
{ldy,imm,VAL},{lda,idx,MRD},{ldx,imm,VAL},{ldz,imm,VAL},/* a0 */
{ldy,zpg,ZRD},{lda,zpg,ZRD},{ldx,zpg,ZRD},{smb,zpg,ZRW},
{tay,imp,0 },{lda,imm,VAL},{tax,imp,0 },{ldz,aba,MRD},
{ldy,aba,MRD},{lda,aba,MRD},{ldx,aba,MRD},{bbs,zpb,ZRD},
{bcs,rel,BRA},{lda,idy,MRD},{lda,inz,MRD},{bcs,rw2,BRA},/* b0 */
{ldy,zpx,ZRD},{lda,zpx,ZRD},{ldx,zpy,ZRD},{smb,zpg,ZRW},
{clv,imp,0 },{lda,aby,MRD},{tsx,imp,0 },{ldz,abx,MRD},
{ldy,abx,MRD},{lda,abx,MRD},{ldx,aby,MRD},{bbs,zpb,ZRD},
{cpy,imm,VAL},{cmp,idx,MRD},{cpz,imm,VAL},{dew,zpg,ZRW2},/* c0 */
{cpy,zpg,ZRD},{cmp,zpg,ZRD},{dec,zpg,ZRW},{smb,zpg,ZRW},
{iny,imp,0 },{cmp,imm,VAL},{dex,imp,0 },{asw,aba,MRW2},
{cpy,aba,MRD},{cmp,aba,MRD},{dec,aba,MRW},{bbs,zpb,ZRD},
{bne,rel,BRA},{cmp,idy,MRD},{cmp,idz,MRD},{bne,rw2,BRA},/* d0 */
{cpz,zpg,MRD},{cmp,zpx,ZRD},{dec,zpx,ZRW},{smb,zpg,ZRW},
{cld,imp,0 },{cmp,aby,MRD},{phx,imp,0 },{phz,imp,0 },
{cpz,aba,MRD},{cmp,abx,MRD},{dec,abx,MRW},{bbs,zpb,ZRD},
{cpx,imm,VAL},{sbc,idx,MRD},{lda,isy,MRD},{inw,zpg,ZRW2},/* e0 */
{cpx,zpg,ZRD},{sbc,zpg,ZRD},{inc,zpg,ZRW},{smb,zpg,ZRW},
{inx,imp,0 },{sbc,imm,VAL},{nop,imp,0 },{row,aba,MRW2},
{cpx,aba,MRD},{sbc,aba,MRD},{inc,aba,MRW},{bbs,zpb,ZRD},
{beq,rel,BRA},{sbc,idy,MRD},{sbc,idz,MRD},{beq,rw2,BRA},/* f0 */
{phw,iw2,VAL},{sbc,zpx,ZRD},{inc,zpx,ZRW},{smb,zpg,ZRW},
{sed,imp,0 },{sbc,aby,MRD},{plx,imp,0 },{plz,imp,0 },
{phw,aba,MRD2},{sbc,abx,MRD},{inc,abx,MRW},{bbs,zpb,ZRD}
};
#endif
/*****************************************************************************
* Disassemble a single opcode starting at pc
*****************************************************************************/
unsigned Dasm6502(char *buffer, unsigned pc)
{
char *dst = buffer;
const char *symbol;
INT8 offset;
INT16 offset16;
unsigned PC = pc;
UINT16 addr, ea;
UINT8 op, opc, arg, access, value;
op = OPCODE(pc++);
switch ( m6502_get_reg(M6502_SUBTYPE) )
{
#if (HAS_M65C02)
case SUBTYPE_65C02:
opc = op65c02[op][0];
arg = op65c02[op][1];
access = op65c02[op][2];
break;
#endif
#if (HAS_M65SC02)
case SUBTYPE_65SC02:
opc = op65sc02[op][0];
arg = op65sc02[op][1];
access = op65sc02[op][2];
break;
#endif
#if (HAS_M6510)
case SUBTYPE_6510:
opc = op6510[op][0];
arg = op6510[op][1];
access = op6510[op][2];
break;
#endif
default:
opc = op6502[op][0];
arg = op6502[op][1];
access = op6502[op][2];
break;
}
dst += sprintf(dst, "%-5s", token[opc]);
if( opc == bbr || opc == bbs || opc == rmb || opc == smb )
dst += sprintf(dst, "%d,", (op >> 3) & 7);
switch(arg)
{
case imp:
break;
case acc:
dst += sprintf(dst,"a");
break;
case rel:
offset = (INT8)ARGBYTE(pc++);
symbol = set_ea_info( 0, pc, offset, access );
dst += sprintf(dst,"%s", symbol);
break;
case rw2:
offset16 = ARGWORD(pc)-1;
pc += 2;
symbol = set_ea_info( 0, pc, offset16, access );
dst += sprintf(dst,"%s", symbol);
break;
case imm:
value = ARGBYTE(pc++);
symbol = set_ea_info( 0, value, EA_UINT8, access );
dst += sprintf(dst,"#%s", symbol);
break;
case zpg:
addr = ARGBYTE(pc++);
symbol = set_ea_info( 0, addr, EA_UINT8, access );
dst += sprintf(dst,"$%02X", addr);
break;
case zpx:
addr = ARGBYTE(pc++);
ea = (addr + m6502_get_reg(M6502_X)) & 0xff;
symbol = set_ea_info( 0, ea, EA_UINT8, access );
dst += sprintf(dst,"$%02X,x", addr);
break;
case zpy:
addr = ARGBYTE(pc++);
ea = (addr + m6502_get_reg(M6502_Y)) & 0xff;
symbol = set_ea_info( 0, ea, EA_UINT8, access );
dst += sprintf(dst,"$%02X,y", addr);
break;
case idx:
addr = ARGBYTE(pc++);
ea = (addr + m6502_get_reg(M6502_X)) & 0xff;
ea = RDMEM(ea) + (RDMEM((ea+1) & 0xff) << 8);
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%02X,x)", addr);
break;
case idy:
addr = ARGBYTE(pc++);
ea = (RDMEM(addr) + (RDMEM((addr+1) & 0xff) << 8) + m6502_get_reg(M6502_Y)) & 0xffff;
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%02X),y", addr);
break;
case zpi:
addr = ARGBYTE(pc++);
ea = RDMEM(addr) + (RDMEM((addr+1) & 0xff) << 8);
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%02X)", addr);
break;
case zpb:
addr = ARGBYTE(pc++);
symbol = set_ea_info( 0, addr, EA_UINT8, access );
dst += sprintf(dst,"$%02X", addr);
offset = (INT8)ARGBYTE(pc++);
symbol = set_ea_info( 1, pc, offset, BRA );
dst += sprintf(dst,",%s", symbol);
break;
case adr:
addr = ARGWORD(pc);
pc += 2;
symbol = set_ea_info( 0, addr, EA_UINT16, access );
dst += sprintf(dst,"%s", symbol);
break;
case aba:
addr = ARGWORD(pc);
pc += 2;
symbol = set_ea_info( 0, addr, EA_UINT16, access );
dst += sprintf(dst,"%s", symbol);
break;
case abx:
addr = ARGWORD(pc);
pc += 2;
ea = (addr + m6502_get_reg(M6502_X)) & 0xffff;
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"$%04X,x", addr);
break;
case aby:
addr = ARGWORD(pc);
pc += 2;
ea = (addr + m6502_get_reg(M6502_Y)) & 0xffff;
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"$%04X,y", addr);
break;
case ind:
addr = ARGWORD(pc);
pc += 2;
ea = ARGWORD(addr);
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%04X)", addr);
break;
case iax:
addr = ARGWORD(pc);
pc += 2;
ea = (ARGWORD(addr) + m6502_get_reg(M6502_X)) & 0xffff;
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%04X),X", addr);
break;
default:
dst += sprintf(dst,"$%02X", op);
}
return pc - PC;
}
#if (HAS_M65CE02 || HAS_M6509 || HAS_M6510 || HAS_M4510)
#if (HAS_65CE02 || HAS_M6510)
static int m6502_get_argword(int addr)
{
return cpu_readop_arg(addr)+(cpu_readop_arg((addr+1)&0xffff) << 8);
}
#endif
#if (HAS_M6509 || HAS_M4510)
static int m6509_get_argword(int addr)
{
if ((addr&0xffff)==0xffff)
return cpu_readop_arg(addr)+(cpu_readop_arg(addr&~0xffff) << 8);
else
return cpu_readop_arg(addr)+(cpu_readop_arg(addr+1) << 8);
}
#endif
typedef struct {
const UINT8 *opcode;
unsigned(*get_reg)(int regnum);
mem_read_handler readmem;
int(*argword)(int addr);
} CPU_TYPE;
#if 0
static CPU_TYPE type_m6502 = {
(const UINT8*)op6502, m6502_get_reg, cpu_readmem16, m6502_get_argword
};
#endif
#ifdef HAS_M6510
static CPU_TYPE type_m6510 = {
(const UINT8*)op6510, m6502_get_reg, cpu_readmem16, m6502_get_argword
};
#endif
#if (HAS_M6509)
static CPU_TYPE type_m6509 = {
(const UINT8*)op6510, m6509_get_reg, cpu_readmem20, m6509_get_argword
};
#endif
#if 0
static CPU_TYPE type_m65c02 = {
(const UINT8*)op65c02, m6502_get_reg, cpu_readmem16, m6502_get_argword
};
static CPU_TYPE type_m65sc02 = {
(const UINT8*)op65sc02, m6502_get_reg, cpu_readmem16, m6502_get_argword
};
#endif
#if (HAS_M65CE02)
static CPU_TYPE type_m65ce02 = {
(const UINT8*)op65ce02, m65ce02_get_reg, cpu_readmem16, m6502_get_argword
};
#endif
#if (HAS_M4510)
static READ_HANDLER(m4510_readmem)
{
return cpu_readmem20( m4510_get_reg(M4510_MEM0+(offset>>13))+offset );
}
static CPU_TYPE type_m4510 = {
(const UINT8*)op65ce02, m4510_get_reg, m4510_readmem, m6509_get_argword
};
#endif
/*****************************************************************************
* Disassemble a single opcode starting at pc
*****************************************************************************/
unsigned int Dasm6502Helper(CPU_TYPE *this, char *buffer, unsigned pc)
{
char *dst = buffer;
const char *symbol;
INT8 offset;
INT16 offset16;
unsigned PC = pc;
UINT16 addr, ea;
UINT8 op, opc, arg, access, value;
op = OPCODE(pc++);
opc = this->opcode[op*3];
arg = this->opcode[op*3+1];
access = this->opcode[op*3+2];
dst += sprintf(dst, "%-5s", token[opc]);
if( opc == bbr || opc == bbs || opc == rmb || opc == smb )
dst += sprintf(dst, "%d,", (op >> 3) & 7);
switch(arg)
{
case imp:
break;
case acc:
dst += sprintf(dst,"a");
break;
case rel:
offset = (INT8)ARGBYTE(pc++);
symbol = set_ea_info( 0, pc, offset, access );
#if 0
dst += sprintf(dst,"%s", symbol);
#else
dst += sprintf(dst,"$%04X", (pc+offset)&0xffff);
#endif
break;
case rw2:
offset16 = this->argword(pc)-1;
pc += 2;
symbol = set_ea_info( 0, pc, offset16, access );
#if 0
dst += sprintf(dst,"%s", symbol);
#else
dst += sprintf(dst,"$%04X", (pc+offset16)&0xffff );
#endif
break;
case imm:
value = ARGBYTE(pc++);
symbol = set_ea_info( 0, value, EA_UINT8, access );
dst += sprintf(dst,"#%s", symbol);
break;
case iw2:
addr = ARGWORD(pc);
pc += 2;
symbol = set_ea_info( 0, addr, EA_UINT16, access );
dst += sprintf(dst,"#%s", symbol);
break;
case zpg:
addr = ARGBYTE(pc++);
symbol = set_ea_info( 0, addr, EA_UINT8, access );
dst += sprintf(dst,"$%02X", addr);
break;
case zpx:
addr = ARGBYTE(pc++);
ea = (addr + this->get_reg(M6502_X)) & 0xff;
symbol = set_ea_info( 0, ea, EA_UINT8, access );
dst += sprintf(dst,"$%02X,x", addr);
break;
case zpy:
addr = ARGBYTE(pc++);
ea = (addr + this->get_reg(M6502_Y)) & 0xff;
symbol = set_ea_info( 0, ea, EA_UINT8, access );
dst += sprintf(dst,"$%02X,y", addr);
break;
case idx:
addr = ARGBYTE(pc++);
ea = (addr + this->get_reg(M6502_X)) & 0xff;
ea = this->readmem(ea) + (this->readmem((ea+1) & 0xff) << 8);
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%02X,x)", addr);
break;
case idy:
addr = ARGBYTE(pc++);
ea = (this->readmem(addr) + (this->readmem((addr+1) & 0xff) << 8)
+ this->get_reg(M6502_Y)) & 0xffff;
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%02X),y", addr);
break;
case idz:
addr = ARGBYTE(pc++);
ea = (this->readmem(addr) + (this->readmem((addr+1) & 0xff) << 8)
+ this->get_reg(M6502_Y)) & 0xffff;
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%02X),z", addr);
break;
case isy:
op = ARGBYTE(pc++);
addr = op+this->get_reg(M6502_S);
ea = (this->readmem(addr)+(this->readmem(addr+1) << 8)+
this->get_reg(M6502_Y)) & 0xffff;
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"(s,$%02X),y", addr);
break;
case zpi:
addr = ARGBYTE(pc++);
ea = this->readmem(addr) + (this->readmem((addr+1) & 0xff) << 8);
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%02X)", addr);
break;
case zpb:
addr = ARGBYTE(pc++);
symbol = set_ea_info( 0, addr, EA_UINT8, access );
dst += sprintf(dst,"$%02X", addr);
offset = (INT8)ARGBYTE(pc++);
symbol = set_ea_info( 1, pc, offset, BRA );
dst += sprintf(dst,",%s", symbol);
break;
case adr:
addr = this->argword(pc);
pc += 2;
symbol = set_ea_info( 0, addr, EA_UINT16, access );
#if 0
dst += sprintf(dst,"%s", symbol);
#else
dst += sprintf(dst, "$%04X", addr);
#endif
break;
case aba:
addr = this->argword(pc);
pc += 2;
symbol = set_ea_info( 0, addr, EA_UINT16, access );
#if 0
dst += sprintf(dst,"%s", symbol);
#else
dst += sprintf(dst, "$%04X", addr);
#endif
break;
case abx:
addr = this->argword(pc);
pc += 2;
ea = (addr + this->get_reg(M6502_X)) & 0xffff;
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"$%04X,x", addr);
break;
case aby:
addr = this->argword(pc);
pc += 2;
ea = (addr + this->get_reg(M6502_Y)) & 0xffff;
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"$%04X,y", addr);
break;
case ind:
addr = this->argword(pc);
pc += 2;
ea = this->argword(addr);
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%04X)", addr);
break;
case iax:
addr = this->argword(pc);
pc += 2;
ea = (this->argword(addr) + this->get_reg(M6502_X)) & 0xffff;
symbol = set_ea_info( 0, ea, EA_UINT16, access );
dst += sprintf(dst,"($%04X),X", addr);
break;
default:
dst += sprintf(dst,"$%02X", op);
}
return pc - PC;
}
#endif
#if (HAS_M65CE02)
/*****************************************************************************
* Disassemble a single opcode starting at pc
*****************************************************************************/
unsigned int Dasm65ce02(char *buffer, unsigned pc)
{
return Dasm6502Helper(&type_m65ce02, buffer, pc);
}
#endif
#if (HAS_M6509)
/*****************************************************************************
* Disassemble a single opcode starting at pc
*****************************************************************************/
unsigned int Dasm6509(char *buffer, unsigned pc)
{
return Dasm6502Helper(&type_m6509, buffer, pc);
}
#endif
#if (HAS_M6510)
/*****************************************************************************
* Disassemble a single opcode starting at pc
*****************************************************************************/
unsigned int Dasm6510(char *buffer, unsigned pc)
{
return Dasm6502Helper(&type_m6510, buffer, pc);
}
#endif
#if (HAS_M4510)
/*****************************************************************************
* Disassemble a single opcode starting at pc
*****************************************************************************/
unsigned int Dasm4510(char *buffer, unsigned pc)
{
return Dasm6502Helper(&type_m4510, buffer, pc);
}
#endif
#endif /* MAME_DEBUG */